By: Allyson Lynch
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import math
from scipy import stats
Plot the popularity distribution by count, cumulative probability, and log probability.
def popularity_plot(class_list, pareto_marker=False, log_plot=False, log_plot_reg=False, file=False):
"""takes a file with smiles strings and popularity calculation information for each category and the optional argument for a log plot and returns distribution plots"""
pareto_df = pd.read_table('Outputs/02 Popularity Files/pareto_split.tsv')
for molecule in class_list:
#make a dataframe per molcule (skip smiles)
smiles_df = pd.read_table('Outputs/02 Popularity Files/'+molecule+'_popularity.tsv')
smiles_df = smiles_df[smiles_df["number_" + molecule]>0] #remove if absent
graph_df = smiles_df.sort_values(by=["number_" + molecule]) #sort by count in increasing order
split_df = pareto_df[pareto_df['molecule']=='number_'+molecule]
#distribution plot
if file:
save_df = graph_df.loc[:, ['smiles', 'rank', "number_" + molecule]] #only include smiles, rank, and number
save_df.to_csv("Outputs/04 Graphs/popularity_plot/" + molecule + "distributionplot.tsv", sep='\t') #save as tsv
plt.figure() #seperate graphs
plot = sns.regplot(x= 'rank', y= "number_" + molecule, data= graph_df, fit_reg=False)
plot.set_title(molecule) #scatterplot of cumulative probabilities
fig = plot.get_figure()
fig.savefig("Outputs/04 Graphs/popularity_plot/"+molecule+"_distributionplot.svg")
#cumulative probability
if file:
save_df = graph_df.loc[:, ['smiles', molecule+"_proportion", molecule+"_rcumulativeprob"]] #only include smiles, rank, number, and cumulative count
save_df.to_csv("Outputs/04 Graphs/popularity_plot/" + molecule + "cumprobplot.tsv", sep='\t') #save as tsv
plt.figure() #seperate graphs
plot = sns.regplot(x= molecule+"_proportion", y= molecule+"_rcumulativeprob", data=graph_df, fit_reg=False)
if pareto_marker:
p=sns.regplot(x='percent_structures', y='percent_amines', data= split_df, fit_reg=False, marker="x", color='r')
p.text(x=split_df['percent_structures']+.03, y=split_df['percent_amines']-.03, s='Pareto split', fontsize=10, fontdict={'color':'r'})
plot.set_title(molecule) #scatterplot of amounts
fig = plot.get_figure()
fig.savefig("Outputs/04 Graphs/popularity_plot/"+molecule+"_cumprobplot.svg")
#log graph
if log_plot:
probability_df = graph_df.sort_values(by=[molecule + "_probability"], ascending=False) #sort by probability in decreasing order
x_values = [math.log(i, 10) for i in range(1, len(probability_df['smiles'].tolist())+1)] #list of rank
y_values = [math.log(i, 10) if i!=0 else 0 for i in probability_df[molecule + "_probability"].tolist()] #list of number
log_df = pd.DataFrame({'log rank':x_values, 'log probability':y_values}) #create dataframe
plt.figure()
if log_plot_reg:
plot = sns.regplot(x= 'log rank', y= 'log probability', data= log_df, fit_reg=True)
slope, intercept, r_value, p_value, std_err = stats.linregress(log_df['log rank'],log_df['log probability'])
print("y="+str(slope)+"x+"+str(intercept)+" r2="+str(r_value**2))
else:
plot = sns.regplot(x= 'log rank', y= 'log probability', data= log_df, fit_reg=False)
plot.set_title("log "+molecule) #scatterplot
fig = plot.get_figure()
fig.savefig("Outputs/04 Graphs/popularity_plot/"+molecule+"_logplot.svg")
Probability distribution of popularvsunpopular or successvsfailure for each property.
def pdf_graph(class_list, properties_file, outcome=False, include_absent_amines=True, file=False):
"""takes a popularity data file, properties data file, and optional parameter for including absent (-1) and returns a histogram of the probability distribution function"""
df_properties = pd.read_table(properties_file)
df_properties_drop = df_properties.drop(['_raw_Reaction number', '_raw_name', '_raw_SMILES', '_raw_SMILES.nosalt', '_rxn_Synthesis_Method', '_raw_Notes', '_out_Outcome'], axis=1)
if outcome:
df_popularity = pd.read_table("Outputs/03 Outcomes/triangle_outcomestats.tsv")
popularity_properties = pd.merge(df_popularity, df_properties, left_on='Smiles', right_on='Smiles', how='right') #merge popularity and properties by smiles
else:
df_popularity = pd.read_table("Outputs/02 Popularity Files/amine_popularity.tsv")
popularity_properties = pd.merge(df_popularity, df_properties, left_on='smiles', right_on='Smiles', how='right') #merge popularity and properties by smiles
popularity_properties[["metalborates_popular"]] = popularity_properties[["metalborates_popular"]].fillna(value=-1) #mark absent
#make a list per molecule...
for molecule in class_list:
#make popular and unpopular data frames
if outcome:
popular_df = popularity_properties.loc[popularity_properties['OUT_anySuccess?']==True] #success dataframe
unpopular_df = popularity_properties.loc[popularity_properties['OUT_anySuccess?']==False] #fail dataframe
else:
popular_df = popularity_properties.loc[popularity_properties[molecule+"_popular"]==1] #popular dataframe
if include_absent_amines:
unpopular_df = popularity_properties.loc[popularity_properties[molecule+"_popular"] <= 0] #unpopular + absent dataframe
else:
unpopular_df = popularity_properties.loc[popularity_properties[molecule+"_popular"]==0] #unpopular dataframe
#...of the pdfs for each property
for prop in df_properties.columns[1:-1]:
#make lists of property
discrete=False #intialize
popular = popular_df[prop].dropna().tolist()
unpopular = unpopular_df[prop].dropna().tolist()
if len(popular)>0:
if type(popular[0])==int:
discrete=True
if discrete:
if outcome:
graph_df = pd.DataFrame(columns=[prop, 'Probability', 'outcome'])
else:
graph_df = pd.DataFrame(columns=[prop, 'Probability', 'popularity'])
short = list(set(popular))
graph_df[prop] = short + short
if outcome:
graph_df['outcome'] = ['success' for i in range(len(short))] + ['failure' for i in range(len(short))]
else:
if include_absent_amines:
graph_df['popularity'] = ['popular' for i in range(len(short))] + ['notpopular' for i in range(len(short))]
else:
graph_df['popularity'] = ['popular' for i in range(len(short))] + ['unpopular' for i in range(len(short))]
graph_df['Probability'] = [popular.count(i)/len(popular) for i in short] + [unpopular.count(i)/len(unpopular) for i in short]
name = prop.replace("/", "_")
if file:
if outcome:
graph_df.to_csv("Outputs/04 Graphs/pdf/"+molecule+"_"+name+"_outcomepdf.tsv", sep='\t') #save as tsv
else:
graph_df.to_csv("Outputs/04 Graphs/pdf/"+molecule+"_"+name+"_pdf.tsv", sep='\t') #save as tsv
plt.figure() #seperate graphs
if outcome:
plot = sns.barplot(x=prop, y='Probability', hue='outcome', data=graph_df, palette=['g','r'])
else:
plot = sns.barplot(x=prop, y='Probability', hue='popularity', data=graph_df, palette=['k','0.50'])
plot.set(title=prop)
fig = plot.get_figure()
if outcome:
fig.savefig("Outputs/04 Graphs/pdf/"+molecule+"_"+name+"_outcomepdfplot.svg")
else:
fig.savefig("Outputs/04 Graphs/pdf/"+molecule+"_"+name+"_pdfplot.svg")
elif type(popular[0])==float:
plt.figure() #seperate graphs
if outcome:
plot = sns.distplot(popular, color='g')
plot = sns.distplot(unpopular, color='r')
else:
plot = sns.distplot(popular, color='k')
plot = sns.distplot(unpopular, color='0.75')
plot.set(title=prop)
fig = plot.get_figure()
prop = prop.replace("/", "_")
if outcome:
fig.savefig("Outputs/04 Graphs/pdf/"+molecule+"_"+prop+"_outcomepdfplot.svg")
else:
fig.savefig("Outputs/04 Graphs/pdf/"+molecule+"_"+prop+"_pdfplot.svg")
Plot the original and triangle manipulated property distribution.
def property_graph(properties_file, file=False):
"""takes a popularity data file, properties data file, and optional parameter for including absent (-1) and returns a histogram of the probability distribution function"""
df_properties = pd.read_table(properties_file, engine='python')
df_properties_drop = df_properties.loc[:, ['Smiles', '_rxn_pH', '_raw_Amine_Mol']]
#pH
graph_df = pd.DataFrame(columns=['_rxn_pH', 'Probability'])
values = df_properties['_rxn_pH'].tolist()
short = list(set(values))
graph_df['_rxn_pH'] = short
graph_df['Probability'] = [values.count(i)/len(values) for i in short]
if file:
graph_df.to_csv("Outputs/04 Graphs/property_graph/"+'_rxn_pH'+properties_file[20:-10]+"_barplot.tsv", sep='\t') #save as tsv
plt.figure() #seperate graphs
plot = sns.barplot(x='_rxn_pH', y='Probability', data=graph_df)
plot.set(title='_rxn_pH')
fig = plot.get_figure()
fig.savefig("Outputs/04 Graphs/property_graph/"+'_rxn_pH'+properties_file[20:-10]+"_barplot.svg")
#amine mols
values = df_properties['_raw_Amine_Mol'].tolist()
plt.figure()
plot = sns.distplot(values)
plot.set(title='_raw_Amine_Mol')
fig = plot.get_figure()
fig.savefig("Outputs/04 Graphs/property_graph/"+'_raw_Amine_Mol'+properties_file[20:-10]+"_barplot.svg")
def graphs(class_list, properties_files, pareto_marker=False, log_plot=False, log_plot_reg=False, include_absent_amines=True, outcome=False, file=False):
popularity_plot(class_list, pareto_marker, log_plot, log_plot_reg, file)
pdf_graph(class_list, properties_files[0], outcome, include_absent_amines, file)
for f in properties_files:
property_graph(f, file)
graphs(["metaloxides", "metalborates"], ["Outputs/03 Outcomes/triangle_clean.tsv", "Outputs/03 Outcomes/human_clean.tsv"], log_plot=True, outcome=True, file=True)
graphs(["metaloxides", "metalborates"], ["Outputs/03 Outcomes/triangle_clean.tsv", "Outputs/03 Outcomes/human_clean.tsv"], log_plot=True, file=True)